maps 패키지
전 세계 나라의 경계선이 입력된 지도 자료이다.
나라의 주별 경계선까지 입력되어 있으나 지도가 1990년 자료를 기준으로 개발되어 업데이트 된 나라와 업데이트 안된 나라가 섞여있다.
col과 fill을 통해 나라별 특징을 시각화 하기 좋다.
미국의 경우 state 까지 세분화 하여 시각화가 가능하다.
library(maps)
library(ggmap)
map("world")
map("world","italy")
map(‘world’)를 이용하면 전세계지도
만약 나라의 이름을 추가한다면 이에 해당하는 나라지도를 그릴 수 있다.
map_data() 함수를 이용하여 원하는 나라에 해당하는 자료를 가지고 올 수 있습니다만, 내용이 빈약합니다.
korea <- map_data("world","South Korea")
head(korea, 20)
## long lat group order region subregion
## 1 126.3270 33.22363 1 1 South Korea Cheju Do
## 2 126.2820 33.20151 1 2 South Korea Cheju Do
## 3 126.2402 33.21484 1 3 South Korea Cheju Do
## 4 126.2290 33.22524 1 4 South Korea Cheju Do
## 5 126.1787 33.28257 1 5 South Korea Cheju Do
## 6 126.1656 33.31201 1 6 South Korea Cheju Do
## 7 126.1994 33.36806 1 7 South Korea Cheju Do
## 8 126.3377 33.46040 1 8 South Korea Cheju Do
## 9 126.6955 33.54932 1 9 South Korea Cheju Do
## 10 126.7599 33.55322 1 10 South Korea Cheju Do
## 11 126.9012 33.51514 1 11 South Korea Cheju Do
## 12 126.9313 33.44385 1 12 South Korea Cheju Do
## 13 126.9054 33.38237 1 13 South Korea Cheju Do
## 14 126.8729 33.34116 1 14 South Korea Cheju Do
## 15 126.7092 33.27168 1 15 South Korea Cheju Do
## 16 126.5817 33.23833 1 16 South Korea Cheju Do
## 17 126.3270 33.22363 1 17 South Korea Cheju Do
## 19 126.7530 34.34399 2 19 South Korea 11
## 20 126.7699 34.29644 2 20 South Korea 11
## 21 126.6891 34.30542 2 21 South Korea 11
unique(korea$subregion)
## [1] "Cheju Do" "11" "3" "21" "5" "Namhae Do"
## [7] "Koje Do" "8" "Ullung Do" "10" NA
한국지도를 시각화 한 후 polygon 함수를 이용하면 제주도에
색을 넣을 수 있지만,
그림의 해상도가 낮아 시각화에 적절한 그림은 아닙니다.
map('world','South Korea')
jeju <- subset(korea, korea$subregion=="Cheju Do")
polygon(jeju$lon,jeju$lat, col="grey")
하지만, 미국의 지도는 maps 패키지만으로 시각화가 가능합니다.
map("state")
map.text("state", add=T)
raster 패키지는 인터넷을 통해 행정, 해발도, 기후 자료들을 다운로드 받아 이를 시각화 할 수 있습니다.
시각화를 위해선 raster 패키지의 설치가 필요합니다.
한국지도를 시각화 한다면 아래와 같이 코드를 입력하면 됩니다.
library(raster)
kor0 <- getData('GADM', country='KOR', level=0)
plot(kor0)
kor1 <- getData('GADM', country='KOR', level=1)
plot(kor1)
kor2 <- getData('GADM', country='KOR', level=2)
plot(kor2)
level 수준에 따라 0은 나라, 1은 시도,
2는 시군구 행정자료입니다.
getData 함수로 다운로드 받은 지도는 plot 함수를 이용하면 간단히 시각화 할 수 있습니다.
이제 raster 패키지에서 다운 받은 그림자료를 이용하여 코로나바이러스감염증-19의 시도별발생동향을 시각화 하겠습니다.
시도별 발생동향을 시각화 하기 위해선 아래의 단계가 필요합니다.
kor1 자료에 발생 현황 수 입력
입력된 자료 범위 선정 후 색 부여
col을 이용한 지도 시각화
그럼 차례대로 지도를 그려보겠습니다.
class(kor1)
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
head(kor1@data)
## GID_0 NAME_0 GID_1 NAME_1
## 1 KOR South Korea KOR.1_1 Busan
## 10 KOR South Korea KOR.2_1 Chungcheongbuk-do
## 11 KOR South Korea KOR.3_1 Chungcheongnam-do
## 12 KOR South Korea KOR.4_1 Daegu
## 13 KOR South Korea KOR.5_1 Daejeon
## 14 KOR South Korea KOR.6_1 Gangwon-do
## VARNAME_1
## 1 Pusan|Busan Gwang'yeogsi|Pusan-gwangyoksi|Fusan
## 10 Chungchongbuk-Do|Chungcheongbugdo|Ch'ungch'ong-bukto|Chusei Hoku-do|North Chungchong|Ch'ungch'ong-bukto
## 11 Chungchongnam-Do|Ch'ungch'ong-namdo|Chusei Nan-do|South Chungchong|Ch'ungch'ong-namdo
## 12 Taegu|Daegu Gwang'yeogsi|Taegu-gwangyoksi|Taikyu
## 13 Daejeon Gwang'yeogsi|Taej<U+014F>n-gwangy<U+014F>ksi|Taiden
## 14 Kang-Won-Do|Gang'weondo|Kangwon-do|Kogen-do|South Kangwon
## NL_NAME_1 TYPE_1 ENGTYPE_1 CC_1 HASC_1
## 1 부산광역시 | 釜山廣域市 Gwangyeoksi Metropolitan City <NA> KR.PU
## 10 충청북도 | 忠淸北道 Do Province <NA> KR.GB
## 11 충청남도 | 忠淸南道 Do Province <NA> KR.GN
## 12 대구광역시 | 大邱廣域市 Gwangyeoksi Metropolitan City <NA> KR.TG
## 13 대구광역시 | 大邱廣域市 Gwangyeoksi Metropolitan City <NA> KR.TJ
## 14 강원도 | 江原道 Do Province <NA> KR.KW
class 함수를 실행시키면 kor1의 속성을 보실 수 있습니다.
공간자료로 구성되어 있으며, 공간자료는 @(slot) 개념을 이용하여 데이터를 관리하고 있습니다.
자료를 보면 한국이름 중 대전이 대구로 잘못 표기되어 있습니다.
따라서 NAME_1을 이용하여 자료를 처리하겠습니다.
이제 NAME_1의 순서대로 확인자수를 확인하여 입력해주세요.
kor1@data$NAME_1
## [1] "Busan" "Chungcheongbuk-do" "Chungcheongnam-do"
## [4] "Daegu" "Daejeon" "Gangwon-do"
## [7] "Gwangju" "Gyeonggi-do" "Gyeongsangbuk-do"
## [10] "Gyeongsangnam-do" "Incheon" "Jeju"
## [13] "Jeollabuk-do" "Jeollanam-do" "Sejong"
## [16] "Seoul" "Ulsan"
confirmed <-c(26151,10928,16287,14350,8309,9706,11173,102984,14540,23941,20455,3900,11259,11454,2514,66067,8302)
kor1@data$confirmed
## NULL
이제 입력된 숫자를 cut 함수와 heat.colors를 이용하여 색을 넣겠습니다.
cut 함수는 임의의 구간으로 자료를 잘라 줍니다.
cut(confirmed, c(0,2000,5000,10000,20000,50000,100000,200000))
## [1] (2e+04,5e+04] (1e+04,2e+04] (1e+04,2e+04] (1e+04,2e+04] (5e+03,1e+04]
## [6] (5e+03,1e+04] (1e+04,2e+04] (1e+05,2e+05] (1e+04,2e+04] (2e+04,5e+04]
## [11] (2e+04,5e+04] (2e+03,5e+03] (1e+04,2e+04] (1e+04,2e+04] (2e+03,5e+03]
## [16] (5e+04,1e+05] (5e+03,1e+04]
## 7 Levels: (0,2e+03] (2e+03,5e+03] (5e+03,1e+04] ... (1e+05,2e+05]
cut 함수의 구분 기준(,)에 맞추어 heat.colors 함수를 연결하면 기준에 맞추어 R에서 자동으로 색상을 줍니다.
cut(confirmed, c(0,2000,5000,10000,20000,50000,100000,200000), heat.colors(7))
## [1] #FFCC00 #FF9900 #FF9900 #FF9900 #FF6600 #FF6600 #FF9900 #FFFF80 #FF9900
## [10] #FFCC00 #FFCC00 #FF3300 #FF9900 #FF9900 #FF3300 #FFFF00 #FF6600
## Levels: #FF0000 #FF3300 #FF6600 #FF9900 #FFCC00 #FFFF00 #FFFF80
이제 kor1 자료에 색상을 넣은 후 이를 시각화 하겠습니다.
사용하지 않으면 원하는 색으로 그림이 그려지지 않습니다.
kor1@data$col=cut(confirmed, c(0,2000,5000,10000,20000,50000,100000,200000), heat.colors(7))
plot(kor1, col=paste(kor1$col))
그림이 잘 그려졌지만 위험한 지역과 안전한 지역의 색이 반대로 된거 같습니다.
rev() 함수를 이용하여 색을 반대로 변환 하겠습니다.
kor1@data$col=cut(confirmed, c(0,2000,5000,10000,20000,50000,100000,200000), rev(heat.colors(7)))
plot(kor1, col=paste(kor1$col))
이제 그림의 중앙에 확인자 수를 넣어보겠습니다.
coordinates 함수를 이용하면 행정지역 별 가운데 위치를 R이 출력해줍니다.
coordinates(kor1)
## [,1] [,2]
## 1 129.0912 35.21142
## 10 127.8182 36.70061
## 11 126.8432 36.52545
## 12 128.5799 35.78117
## 13 127.3786 36.31868
## 14 128.2810 37.71682
## 15 126.8551 35.13442
## 16 127.1861 37.49094
## 17 128.7407 36.30965
## 2 128.2746 35.34559
## 3 126.6268 37.48770
## 4 126.5539 33.38431
## 5 127.1598 35.69758
## 6 126.9695 34.93609
## 7 127.2392 36.54758
## 8 126.9910 37.53330
## 9 129.2414 35.53645
확진자 수가 들어갈 위치의 x와 y의 위치를 lonlat으로 저장한 후 text 함수로 시각화 합니다.
legend(범례)를 추가하여 색상의 범위도 알려주겠습니다.
coordinates(kor1) -> lonlat
plot(kor1, col=paste(kor1$col))
text(x=lonlat[,1], y=lonlat[,2], labels=confirmed, cex=0.7)
legend("bottomright",
legend=c("0-2k","2k-5k","5k-10k","10k-20k","20k-50k","50k-100k","100k-200k"),
fill=rev(heat.colors(7)), cex=0.6)
경기도와 서울특별시의 위치가 중복되기는 하지만 숫자가 들어갈 위치만
조정해주면 그림이 수정됩니다.
title을 이용하면 제목도 설정할 수 있습니다.
R을 이용하지 않더라도 ’SGIS 통계지리정보서비스’를 이용하면 지도에 시각화가 가능합니다.
kor2는 시군구 그림입니다. 만약 수도권(경기도, 서울특별시, 인천광역시)만 선택하여 그림을 그리고 싶다면??
kor2@data를 통해 자료의 구조를 살펴보면 NAME_1을
이용하여 경기도, 서울특별시, 인천광역시를 쉽게 찾을 수 있습니다.
unique() 함수는 중복을 제외한 유일한 하나만 출력시켜주는 함수 입니다.
head(kor2@data)
## GID_0 NAME_0 GID_1 NAME_1 NL_NAME_1 GID_2
## 184167 KOR South Korea KOR.1_1 Busan 부산광역시 | 釜山廣域市 KOR.1.1_1
## 184231 KOR South Korea KOR.1_1 Busan 부산광역시 | 釜山廣域市 KOR.1.2_1
## 184264 KOR South Korea KOR.1_1 Busan 부산광역시 | 釜山廣域市 KOR.1.3_1
## 184196 KOR South Korea KOR.1_1 Busan 부산광역시 | 釜山廣域市 KOR.1.4_1
## 184310 KOR South Korea KOR.1_1 Busan 부산광역시 | 釜山廣域市 KOR.1.5_1
## 184128 KOR South Korea KOR.1_1 Busan 부산광역시 | 釜山廣域市 KOR.1.6_1
## NAME_2 VARNAME_2 NL_NAME_2 TYPE_2 ENGTYPE_2 CC_2 HASC_2
## 184167 Buk <NA> 북구| 北區 Gu District <NA> <NA>
## 184231 Busanjin <NA> 부산진구| 釜山鎭區 Gu District <NA> <NA>
## 184264 Dong <NA> 동구| 東區 Gu District <NA> <NA>
## 184196 Dongnae <NA> 동래구| 東萊區 Gu District <NA> <NA>
## 184310 Gangseo <NA> 강서구| 江西區 Gu District <NA> <NA>
## 184128 Geumjeong <NA> 금정구| 金井區 Gu District <NA> <NA>
unique(kor2@data$NAME_1)
## [1] "Busan" "Chungcheongbuk-do" "Chungcheongnam-do"
## [4] "Daegu" "Daejeon" "Gangwon-do"
## [7] "Gwangju" "Gyeonggi-do" "Gyeongsangbuk-do"
## [10] "Gyeongsangnam-do" "Incheon" "Jeju"
## [13] "Jeollabuk-do" "Jeollanam-do" "Sejong"
## [16] "Seoul" "Ulsan"
이제 subset()를 이용하여 원하는 지역만 추출하겠습니다.
부산 아래의 섬 하나를 인천으로 인식하는 문제가 있습니다.
axis() 함수를 이용하여 그림의 범위를 살펴봅니다.
이 후 xlim과 ylim을 이용하여 그림의 범위를 지정하면 수도권 지역만 선책됩니다.
metro <- subset(kor2, NAME_1 %in% c("Seoul","Gyeonggi-do","Incheon"))
plot(metro)
axis(1)
axis(2)
plot(metro, xlim=c(125,128), ylim=c(36.5,38.5))
head(metro@data)
## GID_0 NAME_0 GID_1 NAME_1 NL_NAME_1 GID_2
## 183025 KOR South Korea KOR.8_1 Gyeonggi-do 경기도 | 京畿道 KOR.8.1_1
## 183141 KOR South Korea KOR.8_1 Gyeonggi-do 경기도 | 京畿道 KOR.8.2_1
## 183010 KOR South Korea KOR.8_1 Gyeonggi-do 경기도 | 京畿道 KOR.8.3_1
## 182961 KOR South Korea KOR.8_1 Gyeonggi-do 경기도 | 京畿道 KOR.8.4_1
## 182758 KOR South Korea KOR.8_1 Gyeonggi-do 경기도 | 京畿道 KOR.8.5_1
## 182742 KOR South Korea KOR.8_1 Gyeonggi-do 경기도 | 京畿道 KOR.8.6_1
## NAME_2 VARNAME_2 NL_NAME_2 TYPE_2 ENGTYPE_2 CC_2 HASC_2
## 183025 Ansan <NA> 안산시| 安山市 Si City <NA> <NA>
## 183141 Ansoeng <NA> 안성시| 安城市 Si City <NA> <NA>
## 183010 Anyang <NA> 안양시| 安養市 Si City <NA> <NA>
## 182961 Bucheon <NA> 부천시| 富川市 Si City <NA> <NA>
## 182758 Dongducheon <NA> 동두천시| 東豆川市 Si City <NA> <NA>
## 182742 Gapyeong <NA> 가평군| 加平郡 Gun County <NA> <NA>
위의 방법을 이용한다면 시군구 별 값과 색도 넣은 그림을 그릴 수 있습니다.
위의 링크를 접속하면 TM 좌표계를 이용한 고용량의 시도, 시군구, 읍면동 자료를 다운로드 하실 수 있습니다.
shp 파일은 arcGIS에서 주로 사용합니다.
shp 파일은 rgdal 패키지의 readOGR 함수로 불러 올 수 있습니다.
shp를 처리에 관한 내용은 수업시간 강의를 진행하겠습니다.
전국표준노드링크도 readOGR 함수로 불러옵니다.
ggmap을 이용하여 배경지도를 그린 후 결과를 시각화 할 수 있습니다.
if(!require(ggplot2))install.packages("ggplot2"); library(ggplot2)
if(!require(ggmap)) install.packages("ggmap"); library(ggmap)
ggmap(get_map(location='south korea', zoom=7))
을 실행시면 error가 발생합니다.
2018년까지 무료로 google지도를 R에서 다운로드 받아 시각화가 가능했지만,
지금은 API가 변경되어 카드를 등록하신 후 이용하실 수
있습니다.
구글지도를 다운로드 받지 않더라도 아래 그림을 그릴 수 있습니다.
library(ggmap)
kor <- c(left = 126.45, bottom = 33.49, right = 126.49, top = 33.52)
map <- get_stamenmap(kor, zoom = 14, maptype = "toner-lite")
ggmap(map)
map <- get_stamenmap(kor, zoom = 6, maptype = "watercolor")
ggmap(map)
만약 유럽 배경지도를 가지고 오고 싶다면?
europe <- c(left = -12, bottom = 35, right = 30, top = 63)
get_stamenmap(europe, zoom = 5) %>% ggmap()
한국지도를 배경으로 와이파이의 분포 그림을 그려보겠습니다.
kor <- c(left = 124, bottom = 33, right = 132, top = 39)
map <- get_stamenmap(kor, zoom = 7, maptype = "toner-lite")
wifi <- read.csv('F:/work/2020/1. 발표/R 시각화 (통계교육원)/day3/Chap13_map2/wifi.csv', header=T) #wifi.csv
head(wifi)
## company lat lon
## 1 KT 37.74417 128.9056
## 2 KT 37.72806 128.9543
## 3 KT 37.75710 128.8900
## 4 KT 37.74769 128.8840
## 5 KT 37.74866 128.9073
## 6 KT 37.74281 128.8827
우리나라 이동통산시의 wifi 설치 위치들입니다.
geom_point를 이용하면 점으로 위치를 표현할 수 있지만 결과가 보기 좋지 않습니다.
ggmap(map) + geom_point(data=wifi, aes(x=lon, y=lat, color=company))
ggmap(map) + geom_point(data=wifi, aes(x=lon, y=lat, color=company)) + facet_grid(.~company)
stat_density_2d를 이용하면 2차원 밀도 그림(열섬그림)을 쉽게 그릴 수 있습니다.
ggmap(map) + stat_density_2d(data=wifi, aes(x=lon, y=lat))
ggmap(map) +
stat_density_2d(data=wifi, aes(x=lon, y=lat, fill=..level.., alpha=..level..), geom='polygon', size=2, bins=30)
..level..은 밀도의 수준을 계산하라는 함수이고 alpha는 투명도를 의미합니다.
geom=’polygon’에서 polygon은 다각형이라는 뜻입니다.
기본은 위에서 본 것처럼 선(線)으로 돼 있는데 그것 말고 도형으로 그리라고 명령을 준 겁니다.
선을 기준으로 size는 선 굵기, bins는 선 간격이라는 뜻입니다.
ggmap(map) +
stat_density_2d(data=wifi, aes(x=lon, y=lat, fill=..level.., alpha=..level..), geom='polygon', size=7, bins=28) +
scale_fill_gradient(low='yellow', high='red', guide=F)+
scale_alpha(range=c(0.02, 0.8), guide=F)
## Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.
## It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.
국내선 항공편도 그림을 그릴 수 있습니다.
airport <- read.csv('F:/work/2020/1. 발표/R 시각화 (통계교육원)/day3/Chap13_map2/airport.csv', header=T) #airport.csv
route <- read.csv('F:/work/2020/1. 발표/R 시각화 (통계교육원)/day3/Chap13_map2/route.csv', header=T) #route.csv
head(airport)
## airport iata lon lat
## 1 강릉 KAG 128.944 37.7536
## 2 광주 KWJ 126.809 35.1264
## 3 군산 KUV 126.616 35.9038
## 4 김포 GMP 126.791 37.5583
## 5 대구 TAE 128.659 35.8941
## 6 목포 MPK 126.380 34.7589
head(route)
## id airport lon lat
## 1 1 CJJ 127.499 36.7166
## 2 7 CJJ 127.499 36.7166
## 3 45 CJJ 127.499 36.7166
## 4 77 CJJ 127.499 36.7166
## 5 2 CJJ 127.499 36.7166
## 6 8 CJJ 127.499 36.7166
ggmap(map) + geom_point(data=airport, aes(x=lon, y=lat, size=3))
ggmap(map) +
geom_point(data=airport, aes(x=lon, y=lat, size=3))+
geom_line(data=route, aes(x=lon, y=lat, group=id))
제주도 노선을 황금색으로 표현해 본다면?
CJU_route<-route[route$airport=="CJU","id"]
route1 <- route[route$id %in% CJU_route,]
ggmap(map) +
geom_point(data=airport, aes(x=lon, y=lat, size=3))+
geom_line(data=route1, aes(x=lon, y=lat, group=id, size=2), col='gold')
leaflat 패키지를 설치하면 오픈지도를 R에서 그릴 수 있습니다.
기본그림은 아래와 같습니다.
library(leaflet)
m <- leaflet() %>%
addTiles()
m
타일을 바꾸면 여러형태의 그림이 표현됩니다.
x <- leaflet() %>%
addTiles() %>%
setView( lng = 2.34, lat = 48.85, zoom = 5 ) %>%
addProviderTiles("NASAGIBS.ViirsEarthAtNight2012")
x
Nasa: NASAGIBS.ViirsEarthAtNight2012
Google map: Esri.WorldImagery
Gray: Esri.WorldGrayCanvas
Terrain: Esri.WorldTerrain
Topo Map: Esri.WorldTopoMap
더 알고 싶다면 here
m <- leaflet() %>%
addTiles() %>%
setView( lng = 2.34, lat = 48.85, zoom = 3 ) %>%
addProviderTiles("Esri.WorldImagery")
m
지도 자료도 시각화가 가능합니다.
# load example data (Fiji Earthquakes) + keep only 100 first lines
data(quakes)
quakes <- head(quakes, 100)
# Create a color palette with handmade bins.
mybins <- seq(4, 6.5, by=0.5)
mypalette <- colorBin( palette="YlOrBr", domain=quakes$mag, na.color="transparent", bins=mybins)
# Prepare the text for the tooltip:
mytext <- paste(
"Depth: ", quakes$depth, "<br/>",
"Stations: ", quakes$stations, "<br/>",
"Magnitude: ", quakes$mag, sep="") %>%
lapply(htmltools::HTML)
# Final Map
m <- leaflet(quakes) %>%
addTiles() %>%
setView( lat=-27, lng=170 , zoom=4) %>%
addProviderTiles("Esri.WorldImagery") %>%
addCircleMarkers(~long, ~lat,
fillColor = ~mypalette(mag), fillOpacity = 0.7, color="white", radius=8, stroke=FALSE,
label = mytext,
labelOptions = labelOptions( style = list("font-weight" = "normal", padding = "3px 8px"), textsize = "13px", direction = "auto")
) %>%
addLegend( pal=mypalette, values=~mag, opacity=0.9, title = "Magnitude", position = "bottomright" )
m